using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Open is an algorithm to open a binary image using a 3x3 kernel using
    /// erosion followed by dilation.
    /// </summary>
    public class Open : BaseForeBackgroundColorFilter
    {
        protected int m_nIterations = 1;
        protected int[] m_aKernel = null;
        
        /// <summary>
        /// Default no-arg constructor.
        /// </summary>
        public Open()
            : this(1, new int[] { 1, 1, 1, 1, 1, 1, 1, 1,1 })
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Open"/> class.
        /// </summary>
        /// <param name="_nIterations">The _n iterations.</param>
        /// <param name="_aKernel">The _a kernel.</param>
        public Open(int _nIterations, int[] _aKernel)
        {
            this.m_nIterations = _nIterations;
            m_aKernel = _aKernel;
        }

        /// <summary>
        /// Gets or sets kernel
        /// </summary>
        public int[] Kernel
        {
            get { return m_aKernel; }
            set { m_aKernel = value; }
        }

        /// <summary>
        /// Gets or sets iterations
        /// </summary>
        public int Iterations
        {
            get { return m_nIterations; }
            set { m_nIterations = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Open"/> class.
        /// </summary>
        /// <param name="_open">The _open.</param>
        internal Open(Open _open)
        {
            this.m_nIterations = _open.m_nIterations;
            this.m_aKernel = _open.m_aKernel;
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            OpenImage(_bitmap, m_aKernel, m_nIterations);
            return _bitmap;
        }

        /// <summary>
        /// Method to open a binary image by eroding and then dilating the image
        /// using the specified kernel.
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <param name="kernel"></param>
        /// <param name="iterations"></param>
        public static void OpenImage(UnsafeBitmap _bitmap, int[] kernel,
                            int iterations)
        {
            new Erode(kernel, iterations).Execute(_bitmap);
            new Dilate(kernel, iterations).Execute(_bitmap);
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Open(this);
        }
    }
}











